package com.fakesmoker.aidawnda.scoring;

import com.fakesmoker.aidawnda.common.ErrorCode;
import com.fakesmoker.aidawnda.exception.BusinessException;
import com.fakesmoker.aidawnda.model.entity.App;
import com.fakesmoker.aidawnda.model.entity.UserAnswer;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author fakesmoker
 */

@Service
@Lazy
public class ScoringStrategyExecutor {

    // 使用ConcurrentHashMap来存储评分策略，以应用类型和评分策略类型作为键，对应的策略实例作为值
    private final Map<Integer, Map<Integer, ScoringStrategy>> scoringStrategyMap = new ConcurrentHashMap<>();

    // 策略列表
    @Resource
    private List<ScoringStrategy> scoringStrategyList;

    @PostConstruct
    public void initScoringStrategyMap() {
        for (ScoringStrategy strategy : scoringStrategyList) {
            if (strategy.getClass().isAnnotationPresent(ScoringStrategyConfigAnnotation.class)) {
                ScoringStrategyConfigAnnotation scoringStrategyConfig = strategy.getClass().getAnnotation(ScoringStrategyConfigAnnotation.class);
                int appType = scoringStrategyConfig.appType();
                int scoringStrategy = scoringStrategyConfig.scoringStrategy();
                scoringStrategyMap
                        .computeIfAbsent(appType, k -> new ConcurrentHashMap<>())
                        .computeIfAbsent(scoringStrategy, k -> strategy);
            }
        }
    }
    /**
     * 评分
     *
     * @param choiceList
     * @param app
     * @return
     * @throws Exception
     */
    public UserAnswer doScore(List<String> choiceList, App app) throws Exception {
        Integer appType = app.getAppType();
        Integer appScoringStrategy = app.getScoringStrategy();
        if (appType == null || appScoringStrategy == null) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "应用配置有误，未找到匹配的策略");
        }

        // 根据应用类型和评分策略类型从scoringStrategyMap中获取对应的策略实例
        ScoringStrategy strategy = scoringStrategyMap
         .getOrDefault(appType, new ConcurrentHashMap<>())
         .getOrDefault(appScoringStrategy, null);

        if (strategy == null) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "应用过配置有误，未找到匹配的策略");
        }

        return strategy.doScore(choiceList, app);
    }
}